<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<title>流程设计 </title>
<body>
<script src="https://cdn.bootcss.com/jquery/3.6.0/jquery.min.js"></script>
<script src="/js/go.js"></script>
<div>
<!--    <div style="margin-top: 5px;margin-bottom: 5px;">
        <input type="text" id="flowName" th:value="${flow?.title}" placeholder="name">
        <input type="text" id="flowType" th:value="${flow?.type}" placeholder="type">
        <button id="SaveButton" onclick="save()">Save</button>
        <button onclick="load()">Load</button>
         <button onclick="layout()">Layout</button>
    </div>-->
    <div id="sample">
        <div style="width: 100%; display: flex; justify-content: space-between">
        <!--    <div id="myPaletteDiv"
                 style="width: 100px; margin-right: 2px; background-color: whitesmoke; border: solid 1px black"></div>-->
            <div id="myDiagramDiv" style="flex-grow: 1; height: 480px; border: solid 1px black"></div>
        </div>

    </div>
    <!-- <input type="text" id="cardId" class="form-control" th:value="${cardId}" hidden>-->
    <input type="text" id="flowId" class="form-control" th:value="${flow?.id}" hidden>
    <input type="text" id="ndata" class="form-control" th:value="${flow?.flow?.getNodeDataArrayJsonStr()}" hidden>
    <input type="text" id="ldata" class="form-control" th:value="${flow?.flow?.getLinkDataArrayJsonStr()}" hidden>

</div>
</body>
<script>
    function init() {
        var $ = go.GraphObject.make;  // for conciseness in defining templates

        var yellowgrad = $(go.Brush, "Linear", {0: "rgb(254, 201, 0)", 1: "rgb(254, 162, 0)"});
        var greengrad = $(go.Brush, "Linear", {0: "#98FB98", 1: "#9ACD32"});
        var bluegrad = $(go.Brush, "Linear", {0: "#B0E0E6", 1: "#87CEEB"});
        var redgrad = $(go.Brush, "Linear", {0: "#C45245", 1: "#871E1B"});
        var whitegrad = $(go.Brush, "Linear", {0: "#F0F8FF", 1: "#E6E6FA"});

        var bigfont = "bold 13pt Helvetica, Arial, sans-serif";
        var smallfont = "bold 11pt Helvetica, Arial, sans-serif";

        // Common text styling
        function textStyle() {
            return {
                margin: 6,
                wrap: go.TextBlock.WrapFit,
                textAlign: "center",
                editable: true,
                font: bigfont
            }
        }

        myDiagram =
            $(go.Diagram, "myDiagramDiv",
                {
                    // have mouse wheel events zoom in and out instead of scroll up and down
                    "toolManager.mouseWheelBehavior": go.ToolManager.WheelZoom,
                    initialAutoScale: go.Diagram.Uniform,
                    "linkingTool.direction": go.LinkingTool.ForwardsOnly,
                    layout: $(go.LayeredDigraphLayout, {isInitial: false, isOngoing: false, layerSpacing: 50}),
                    "undoManager.isEnabled": true,

                    allowMove: false,
                    allowHorizontalScroll: false,
                    allowVerticalScroll: false,
                    allowSelect: false,
                });

        // when the document is modified, add a "*" to the title and enable the "Save" button
        myDiagram.addDiagramListener("Modified", function (e) {
            /*  var button = document.getElementById("SaveButton");
              if (button) button.disabled = !myDiagram.isModified;*/
            var idx = document.title.indexOf("修改-未保存");
            if (myDiagram.isModified) {
                if (idx < 0) document.title += "修改-未保存";
            } else {
                if (idx >= 0) document.title = document.title.substr(0, idx);
            }
        });

        var defaultAdornment =
            $(go.Adornment, "Spot",
                $(go.Panel, "Auto",
                    $(go.Shape, {fill: null, stroke: "dodgerblue", strokeWidth: 4}),
                    $(go.Placeholder)),
                // the button to create a "next" node, at the top-right corner
                $("Button",
                    {
                        alignment: go.Spot.TopRight,
                        click: addNodeAndLink
                    },  // this function is defined below
                    new go.Binding("visible", "", function (a) {
                        return !a.diagram.isReadOnly;
                    }).ofObject(),
                    $(go.Shape, "PlusLine", {desiredSize: new go.Size(6, 6)})
                )
            );

        // define the Node template
        myDiagram.nodeTemplate =
            $(go.Node, "Auto",
                {selectionAdornmentTemplate: defaultAdornment},
                new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
                // define the node's outer shape, which will surround the TextBlock
                $(go.Shape, "Rectangle",
                    {
                        fill: yellowgrad, stroke: "black",
                        portId: "", fromLinkable: true, toLinkable: true, cursor: "pointer",
                        toEndSegmentLength: 50, fromEndSegmentLength: 40
                    }),
                $(go.TextBlock, "Process",
                    {
                        margin: 6,
                        font: bigfont,
                        editable: true
                    },
                    new go.Binding("text", "text").makeTwoWay()));

        myDiagram.nodeTemplateMap.add("Source",
            $(go.Node, "Auto",
                new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
                $(go.Shape, "RoundedRectangle",
                    {
                        fill: bluegrad,
                        portId: "", fromLinkable: true, cursor: "pointer", fromEndSegmentLength: 40
                    }),
                $(go.TextBlock, "User", textStyle(),
                    new go.Binding("text", "text").makeTwoWay())
            ));

        myDiagram.nodeTemplateMap.add("DesiredEvent",
            $(go.Node, "Auto",
                new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
                $(go.Shape, "RoundedRectangle",
                    {fill: greengrad, portId: "", toLinkable: true, toEndSegmentLength: 50}),
                $(go.TextBlock, "Success!", textStyle(),
                    new go.Binding("text", "text").makeTwoWay())
            ));

        // Undesired events have a special adornment that allows adding additional "reasons"
        var UndesiredEventAdornment =
            $(go.Adornment, "Spot",
                $(go.Panel, "Auto",
                    $(go.Shape, {fill: null, stroke: "dodgerblue", strokeWidth: 4}),
                    $(go.Placeholder)),
                // the button to create a "next" node, at the top-right corner
                $("Button",
                    {
                        alignment: go.Spot.BottomRight,
                        click: addReason
                    },  // this function is defined below
                    new go.Binding("visible", "", function (a) {
                        return !a.diagram.isReadOnly;
                    }).ofObject(),
                    $(go.Shape, "TriangleDown", {desiredSize: new go.Size(10, 10)})
                )
            );

        var reasonTemplate = $(go.Panel, "Horizontal",
            $(go.TextBlock, "Reason",
                {
                    margin: new go.Margin(4, 0, 0, 0),
                    maxSize: new go.Size(200, NaN),
                    wrap: go.TextBlock.WrapFit,
                    stroke: "whitesmoke",
                    editable: true,
                    font: smallfont
                },
                new go.Binding("text", "text").makeTwoWay())
        );


        myDiagram.nodeTemplateMap.add("UndesiredEvent",
            $(go.Node, "Auto",
                new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
                {selectionAdornmentTemplate: UndesiredEventAdornment},
                $(go.Shape, "RoundedRectangle",
                    {fill: redgrad, portId: "", toLinkable: true, toEndSegmentLength: 50}),
                $(go.Panel, "Vertical", {defaultAlignment: go.Spot.TopLeft},

                    $(go.TextBlock, "Drop", textStyle(),
                        {
                            stroke: "whitesmoke",
                            minSize: new go.Size(80, NaN)
                        },
                        new go.Binding("text", "text").makeTwoWay()),

                    $(go.Panel, "Vertical",
                        {
                            defaultAlignment: go.Spot.TopLeft,
                            itemTemplate: reasonTemplate
                        },
                        new go.Binding("itemArray", "reasonsList").makeTwoWay()
                    )
                )
            ));

        myDiagram.nodeTemplateMap.add("Comment",
            $(go.Node, "Auto",
                new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
                $(go.Shape, "Rectangle",
                    {portId: "", fill: whitegrad, fromLinkable: true}),
                $(go.TextBlock, "A comment",
                    {
                        margin: 9,
                        maxSize: new go.Size(200, NaN),
                        wrap: go.TextBlock.WrapFit,
                        editable: true,
                        font: smallfont
                    },
                    new go.Binding("text", "text").makeTwoWay())
                // no ports, because no links are allowed to connect with a comment
            ));

        // clicking the button on an UndesiredEvent node inserts a new text object into the panel
        function addReason(e, obj) {
            var adorn = obj.part;
            if (adorn === null) return;
            e.handled = true;
            var arr = adorn.adornedPart.data.reasonsList;
            myDiagram.startTransaction("add reason");
            myDiagram.model.addArrayItem(arr, {});
            myDiagram.commitTransaction("add reason");
        }

        // clicking the button of a default node inserts a new node to the right of the selected node,
        // and adds a link to that new node
        function addNodeAndLink(e, obj) {
            var adorn = obj.part;
            if (adorn === null) return;
            e.handled = true;
            var diagram = adorn.diagram;
            diagram.startTransaction("Add State");
            // get the node data for which the user clicked the button
            var fromNode = adorn.adornedPart;
            var fromData = fromNode.data;
            // create a new "State" data object, positioned off to the right of the adorned Node
            var toData = {text: "new"};
            var p = fromNode.location;
            toData.loc = p.x + 200 + " " + p.y;  // the "loc" property is a string, not a Point object
            // add the new node data to the model
            var model = diagram.model;
            model.addNodeData(toData);
            // create a link data from the old node data to the new node data
            var linkdata = {};
            linkdata[model.linkFromKeyProperty] = model.getKeyForNodeData(fromData);
            linkdata[model.linkToKeyProperty] = model.getKeyForNodeData(toData);
            // and add the link data to the model
            model.addLinkData(linkdata);
            // select the new Node
            var newnode = diagram.findNodeForData(toData);
            diagram.select(newnode);
            diagram.commitTransaction("Add State");
        }

        // replace the default Link template in the linkTemplateMap
        myDiagram.linkTemplate =
            $(go.Link,  // the whole link panel
                new go.Binding("points").makeTwoWay(),
                {curve: go.Link.Bezier, toShortLength: 15},
                new go.Binding("curviness", "curviness"),
                $(go.Shape,  // the link shape
                    {stroke: "#2F4F4F", strokeWidth: 2.5}),
                $(go.Shape,  // the arrowhead
                    {toArrow: "kite", fill: "#2F4F4F", stroke: null, scale: 2})
            );

        myDiagram.linkTemplateMap.add("Comment",
            $(go.Link, {selectable: false},
                $(go.Shape, {strokeWidth: 2, stroke: "darkgreen"})));


/*        var palette =
            $(go.Palette, "myPaletteDiv",  // create a new Palette in the HTML DIV element
                {
                    // share the template map with the Palette
                    nodeTemplateMap: myDiagram.nodeTemplateMap,
                    autoScale: go.Diagram.Uniform  // everything always fits in viewport
                });

        palette.model.nodeDataArray = [
            {category: "Source"},
            {}, // default node
            {category: "DesiredEvent"},
            {category: "UndesiredEvent", reasonsList: [{}]},
            {category: "Comment"}
        ];*/

        // read in the JSON-format data from the "mySavedModel" element
        load();
        layout();
    }

    function layout() {
        myDiagram.layoutDiagram(true);
    }

    // Show the diagram's model in JSON format
    function save() {
        let toJson = myDiagram.model.toJson();
        let flowId = $("#flowId").val();
        let flowName = $("#flowName").val();
        let flowType = $("#flowType").val();
        let testinfo = {"id": flowId, "title": flowName,"type": flowType, "flow": JSON.parse(toJson)}
        console.log(testinfo);
        $.ajax({
            type: "post",
            url: "/card/flow",
            data: JSON.stringify(testinfo),
            async: false,
            contentType: 'application/json',
            dataType: 'JSON',
            success: function (obj) {
                myDiagram.layoutDiagram(true);
            }
        });

        myDiagram.isModified = false;
    }

    function load() {
        let flowId = $("#flowId").val();
        if (flowId === "") {
            return;
        }

        let model = {
            "class": "go.GraphLinksModel",
            "copiesArrays": true,
            "copiesArrayObjects": true,
            "nodeDataArray": JSON.parse($("#ndata").val()),
            "linkDataArray": JSON.parse($("#ldata").val())
        }
        myDiagram.model = go.Model.fromJson(JSON.stringify(model));
    }

    window.addEventListener('DOMContentLoaded', init);


</script>
</html>





